home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XA_6S.ZIP / SOURCE / WIND_FNS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-18  |  19.9 KB  |  795 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <OSBIND.H>
  11. #include <memory.h>
  12. #include "XA_DEFS.H"
  13. #include "XA_TYPES.H"
  14. #include "XA_GLOBL.H"
  15. #include "K_DEFS.H"
  16. #include "C_WINDOW.H"
  17. #include "EVENTS.H"
  18. #include "RECTLIST.H"
  19. #include "SCRLWIDG.H"
  20. #include "INFOWIDG.H"
  21. #include "TITLWIDG.H"
  22. #include "STD_WIDG.H"
  23. #include "graf_mou.h"
  24. #include "messages.h"
  25. #include "desktop.h"
  26. #include "RESOURCE.H"
  27. #include "SYSTEM.H"
  28. #include "OBJECTS.H"
  29.  
  30. /*
  31.     AES window handling functions
  32.     I've tried to support some of the AES4 extensions here as well as the plain
  33.     single tasking GEM ones.
  34. */
  35. unsigned long XA_wind_create(short clnt_pid, AESPB *pb)
  36. {
  37.     XA_WINDOW *new_window;
  38.     long tp=0;
  39.     
  40.     tp=pb->intin[0];
  41.     
  42.     new_window=create_window(clnt_pid, tp, pb->intin[1], pb->intin[2], pb->intin[3], pb->intin[4]);
  43.  
  44.     if (new_window)
  45.         pb->intout[0]=new_window->handle;    /* Return the window handle in intout[0] */
  46.     else
  47.         pb->intout[0]=-1;                    /* Fail to create window, return -ve number */
  48.  
  49.     return XAC_DONE;    /* Allow the kernal to wake up the client - we've done our bit */
  50. }
  51.  
  52. unsigned long XA_wind_open(short clnt_pid,AESPB *pb)
  53. {
  54.     XA_WINDOW *w,*wl;
  55.     XA_CLIENT *client=Pid2Client(clnt_pid);
  56.  
  57.     w=get_wind_by_handle(pb->intin[0]);    /* Get the window */
  58.  
  59.     if (w==NULL)
  60.     {
  61.         DIAGS(("WARNING:wind_open:Invalid window handle\n"));
  62.         pb->intout[0]=0;            /* Invalid window handle, return error */
  63.         return XAC_DONE;
  64.     }
  65.     
  66.     pb->intout[0]=1;                /* return ok in intout[0] */
  67.     
  68.     if (w->is_open==TRUE)            /* the window is already open, no need to do anything */
  69.     {
  70.         DIAGS(("WARNING: Attempt to open window when it was already open\n"));
  71.         return XAC_DONE;
  72.     }
  73.  
  74.     /* New top window - change the cursor to this clients choice */
  75.     graf_mouse(client->client_mouse, client->client_mouse_form);
  76.  
  77.     w->x=pb->intin[1];                /* Change the window coords */
  78.     w->y=pb->intin[2];
  79.     w->w=pb->intin[3];
  80.     w->h=pb->intin[4];
  81.     w->is_open=TRUE;                /* Flag window as open */
  82.     w->window_status=XAWS_OPEN;
  83.     
  84.     pull_wind_to_top(w);            /* Newly opened windows begin on top */
  85.  
  86.     wl=w->next;
  87.  
  88.     v_hide_c(V_handle);
  89.  
  90.     calc_work_area(w);
  91.  
  92.     display_non_topped_window(w,NULL);    /* Display the window (use the non-topped method as it sets clipping rectangles) */
  93.     send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->x, w->y, w->w, w->h);
  94.  
  95.     if (wl!=root_window)        /* Refresh the previous top window as being 'non-topped' */
  96.     {
  97.         display_non_topped_window(wl,NULL);
  98.         send_app_message(wl->owner, WM_UNTOPPED, 0, wl->handle, wl->x, wl->y, wl->w, wl->h);
  99.     }
  100.  
  101.     v_show_c(V_handle,1);
  102.  
  103.     return XAC_DONE;
  104. }
  105.  
  106. unsigned long XA_wind_close(short clnt_pid,AESPB *pb)
  107. {
  108.     XA_WINDOW *w;
  109.     
  110.     w=get_wind_by_handle(pb->intin[0]);    /* Get the window */
  111.  
  112.     if (w==NULL)
  113.     {
  114.         DIAGS(("WARNING:wind_close:Invalid window handle\n"));
  115.         pb->intout[0]=0;            /* Invalid window handle, return error */
  116.         return XAC_DONE;
  117.     }
  118.  
  119.     if (w->owner!=clnt_pid)        /* Clients can only close their own windows */
  120.     {
  121.         DIAGS(("WARNING: clnt %d cannot close window %d (not owner)\n",clnt_pid,w->handle));
  122.         pb->intout[0]=0;            /* Invalid window handle, return error */
  123.         return XAC_DONE;
  124.     }
  125.     
  126.     pb->intout[0]=close_window(w);
  127.     
  128.     return XAC_DONE;
  129. }
  130.  
  131. unsigned long XA_wind_find(short clnt_pid,AESPB *pb)
  132. {
  133.     XA_WINDOW *w;
  134.     
  135.     w=wind_find(pb->intin[0], pb->intin[1]);    /* Is there a window under the mouse? */
  136.  
  137.     if (w==NULL)
  138.     {
  139.         pb->intout[0]=0;
  140.         return XAC_DONE;
  141.     }
  142.  
  143.     pb->intout[0]=w->handle;    /* Found a window, return the handle */
  144.  
  145.     return XAC_DONE;
  146. }
  147.  
  148. void update_vslide(XA_WINDOW *wind)
  149. {
  150.     XA_RECT_LIST *rl;
  151.     short x,y,pnt[4];
  152.     XA_WIDGET *widg=wind->widgets;
  153.  
  154.     widg+=XAW_VSLIDE;
  155.     
  156.     rp_2_ap(wind, widg, &x, &y);    /* Convert relative coords and window location to absolute screen location */
  157.     pnt[0]=x; pnt[1]=y;
  158.     pnt[2]=x+widg->w; pnt[3]=y+widg->h;
  159.     vsf_color(V_handle,display.dial_colours.bg_col);
  160.     vsf_interior(V_handle,FIS_SOLID);
  161.     
  162.     v_hide_c(V_handle);
  163.     for(rl=rect_get_system_first(wind); rl; rl=rect_get_system_next(wind))                /* Walk the rectangle list */
  164.     {
  165.         set_clip(rl->x, rl->y, rl->w, rl->h);
  166.         v_bar(V_handle,pnt);
  167.         display_vslide(wind, widg);
  168.     }
  169.     v_show_c(V_handle,1);
  170. }
  171.  
  172. void update_hslide(XA_WINDOW *wind)
  173. {
  174.     XA_RECT_LIST *rl;
  175.     short x,y,pnt[4];
  176.     XA_WIDGET *widg=wind->widgets;
  177.     
  178.     widg+=XAW_HSLIDE;
  179.     
  180.     rp_2_ap(wind, widg, &x, &y);    /* Convert relative coords and window location to absolute screen location */
  181.     pnt[0]=x; pnt[1]=y;
  182.     pnt[2]=x+widg->w; pnt[3]=y+widg->h;
  183.     vsf_color(V_handle,display.dial_colours.bg_col);
  184.     vsf_interior(V_handle,FIS_SOLID);
  185.     vsf_color(V_handle,display.dial_colours.bg_col);
  186.     vsf_interior(V_handle,FIS_SOLID);
  187.     
  188.     v_hide_c(V_handle);
  189.     for(rl=rect_get_system_first(wind); rl; rl=rect_get_system_next(wind))                /* Walk the rectangle list */
  190.     {
  191.         set_clip(rl->x, rl->y, rl->w, rl->h);
  192.         v_bar(V_handle,pnt);
  193.         display_hslide(wind, widg);
  194.     }
  195.     v_show_c(V_handle,1);
  196. }
  197.  
  198. unsigned long XA_wind_set(short clnt_pid, AESPB *pb)
  199. {
  200.     XA_WINDOW *w,*wl;
  201.     OBJECT *ob;
  202.     GRECT clip,our_win;
  203.     XA_CLIENT *client=Pid2Client(clnt_pid);
  204.     short wind=pb->intin[0],cmd=pb->intin[1],is_top;
  205.     unsigned short *l;
  206.     char *t;
  207.     
  208.     w=get_wind_by_handle(wind);
  209.  
  210.     if (w==NULL)
  211.     {
  212.         DIAGS(("WARNING:wind_set:Invalid window handle =%d\n",w));
  213.         pb->intout[0]=0;            /* Invalid window handle, return error */
  214.         return XAC_DONE;
  215.     }
  216.  
  217.     if ((w->owner!=clnt_pid)        /* Clients can only change their own windows */
  218.         &&((w!=root_window)||(cmd!=WF_NEWDESK)))
  219.     {
  220.         DIAGS(("WARNING: clnt %d cannot change window %d (not owner)\n",clnt_pid,w->handle));
  221.         pb->intout[0]=0;            /* Invalid window handle, return error */
  222.         return XAC_DONE;
  223.     }
  224.     
  225.     switch(cmd)
  226.     {
  227.         case WF_HSLIDE:
  228.             if (w->widgets[XAW_HSLIDE].stuff)
  229.             {
  230.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  231.                 short p=pb->intin[2];
  232.                 
  233.                 if (p<0) p=0;
  234.                 if (p>1000) p=1000;
  235.                 
  236.                 slw->position=p;
  237.                 
  238.                 update_hslide(w);
  239.             }
  240.             break;
  241.         case WF_VSLIDE:
  242.             if (w->widgets[XAW_VSLIDE].stuff)
  243.             {
  244.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  245.                 short p=pb->intin[2];
  246.                 
  247.                 if (p<0) p=0;
  248.                 if (p>1000) p=1000;
  249.                 
  250.                 slw->position=p;
  251.                 update_vslide(w);
  252.             }
  253.             break;
  254.         case WF_HSLSIZE:
  255.             if (w->widgets[XAW_HSLIDE].stuff)
  256.             {
  257.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  258.                 short p=pb->intin[2];
  259.                 
  260.                 if (p<0) p=0;
  261.                 if (p>1000) p=1000;
  262.                 
  263.                 slw->length=p;
  264.                 update_hslide(w);
  265.             }
  266.             break;
  267.         case WF_VSLSIZE:
  268.             if (w->widgets[XAW_VSLIDE].stuff)
  269.             {
  270.                 XA_SLIDER_WIDGET *slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  271.                 short p=pb->intin[2];
  272.                 
  273.                 if (p<0) p=0;
  274.                 if (p>1000) p=1000;
  275.                 
  276.                 slw->length=p;
  277.                 update_vslide(w);
  278.             }
  279.             break;
  280.         case WF_NAME:
  281.             l=(unsigned short*)(pb->intin);
  282.             t=(char*)(l[2]<<16);
  283.             t+=l[3];
  284.             w->widgets[XAW_TITLE].stuff=(void*)t;
  285.  
  286.             v_hide_c(V_handle);
  287.             if (w->is_open)
  288.             {
  289.                 rp_2_ap(w, w->widgets+XAW_TITLE, &clip.g_x, &clip.g_y);
  290.     
  291.                 clip.g_w=w->widgets[XAW_TITLE].w;
  292.                 clip.g_h=w->widgets[XAW_TITLE].h;
  293.  
  294.                 display_non_topped_window(w,&clip);
  295.             }
  296.             v_show_c(V_handle,1);
  297.             break;
  298.         case WF_INFO:
  299.             l=(unsigned short*)(pb->intin);
  300.             t=(char*)(l[2]<<16);
  301.             t+=l[3];
  302.             w->widgets[XAW_INFO].stuff=(void*)t;
  303.  
  304.             v_hide_c(V_handle);
  305.             if ((w->active_widgets&INFO)&&(w->is_open))
  306.             {
  307.                 rp_2_ap(w, w->widgets+XAW_INFO, &clip.g_x, &clip.g_y);
  308.     
  309.                 clip.g_w=w->widgets[XAW_INFO].w;
  310.                 clip.g_h=w->widgets[XAW_INFO].h;
  311.  
  312.                 display_non_topped_window(w,&clip);
  313.             }
  314.             v_show_c(V_handle,1);
  315.             break;
  316.  
  317.         case WF_CURRXYWH:            /* Move a window */
  318.             move_window(w,pb->intin[2],pb->intin[3],pb->intin[4],pb->intin[5]);
  319.             break;
  320.  
  321.         case WF_BOTTOM:                /* Extension, send window to the bottom */
  322.             v_hide_c(V_handle);
  323.  
  324.             wl=w->next;
  325.             is_top=(w==window_list);
  326.             
  327.             send_wind_to_bottom(w);            /* Send it to the back */
  328.  
  329.             our_win.g_x=w->x; our_win.g_y=w->y;
  330.             our_win.g_w=w->w; our_win.g_h=w->h;
  331.             
  332.             while(wl!=root_window)
  333.             {
  334.                 clip.g_x=wl->x; clip.g_y=wl->y;
  335.                 clip.g_w=wl->w; clip.g_h=wl->h;
  336.                 
  337.                 if (rc_intersect(&our_win,&clip))
  338.                 {
  339.                     display_non_topped_window(window_list,&clip);    /* Re-display any revealed windows */
  340.                     if (!(wl->active_widgets&NO_MESSAGES))
  341.                     {
  342.                         send_app_message(wl->owner, WM_REDRAW, 0, wl->handle, clip.g_x, clip.g_y, clip.g_w, clip.g_h);
  343.                     }
  344.                 }
  345.                 wl=wl->next;
  346.             }
  347.             
  348.             if (is_top)
  349.             {
  350.                 display_non_topped_window(window_list, NULL);    /* Re-display new top window */
  351.                 if (!(window_list->active_widgets&NO_MESSAGES))
  352.                 {
  353.                     send_app_message(window_list->owner, WM_ONTOP, 0, window_list->handle, 0, 0, 0, 0);
  354.                     send_app_message(window_list->owner, WM_REDRAW, 0, window_list->handle, window_list->wx, window_list->wy, window_list->ww, window_list->wh);
  355.                 }
  356.             }
  357.  
  358.             v_show_c(V_handle,1);
  359.             break;
  360.             
  361.         case WF_TOP:                /* Top the window */
  362.             if (w->is_open)
  363.             {
  364.                 Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  365.  
  366.                 pull_wind_to_top(w);
  367.                                 /* New top window - change the cursor to this clients choice */
  368.                 graf_mouse(client->client_mouse, client->client_mouse_form);
  369.             
  370.                 v_hide_c(V_handle);
  371.  
  372.                 if ((window_list->next)&&(window_list->next->is_open))
  373.                     display_non_topped_window(window_list->next,NULL);
  374.             
  375.                 Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  376.  
  377.                 display_non_topped_window(w,NULL);    /* Display the window */
  378.  
  379.                 v_show_c(V_handle,1);
  380.                 send_app_message(clnt_pid, WM_REDRAW, 0, w->handle, w->x, w->y, w->w, w->h);
  381.             }
  382.             
  383.             break;
  384.             
  385.         case WF_NEWDESK:    /* Set a new desktop object tree */
  386.             l=(unsigned short*)pb->intin;
  387.             t=(char*)(l[2]<<16);
  388.             t+=l[3];
  389.             ob=(OBJECT*)t;
  390.             
  391.             if (ob)
  392.             {
  393.                 client->desktop=ob;
  394.                 set_desktop(ob);
  395.                 root_window->owner=clnt_pid;
  396.             }else{
  397.                 client->desktop=NULL;
  398.                 set_desktop((OBJECT*)ResourceTree(system_resources,DEF_DESKTOP));
  399.             }
  400.  
  401.             v_hide_c(V_handle);
  402.             display_non_topped_window(root_window,NULL);
  403.             v_show_c(V_handle,1);
  404.             
  405.             break;
  406.             
  407.         case WF_AUTOREDRAW:        /* Set an auto-redraw callback function for the window */
  408.             l=(unsigned short*)pb->intin;
  409.             t=(char*)(l[2]<<16);
  410.             t+=l[3];
  411.             w->redraw=(WindowDisplayCallback)t;
  412.             break;
  413.             
  414.         case WF_STOREBACK:        /* Set the window's 'preserve own background' attribute */
  415.             w->background=(void*)malloc(display.planes*((w->w+35)>>2)*(w->h+20));
  416.             w->bgx=-1;
  417.             w->active_widgets|=STORE_BACK|NO_REDRAWS;
  418.             break;
  419.         
  420.         case WF_ICONIFY:        /* Iconify a window */
  421.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  422.             move_window(w,pb->intin[2],pb->intin[3],pb->intin[4],pb->intin[5]);
  423.             w->window_status=XAWS_ICONIFIED;
  424.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  425.             break;
  426.  
  427.         case WF_UNICONIFY:        /* Un-Iconify a window */
  428.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  429.             move_window(w,w->prev_x,w->prev_y,w->prev_w,w->prev_h);
  430.             w->window_status=XAWS_OPEN;
  431.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  432.             break;
  433.  
  434.     }
  435.  
  436.     pb->intout[0]=1;
  437.     return XAC_DONE;
  438. }
  439.  
  440. /* AES wind_get() function. */
  441. /* This includes support for most of the AES4 / AES4.1 extensions, */
  442. /* with the exception of WF_BEVENT (all XaAES windows get button events in the */
  443. /* background at the moment). */
  444. unsigned long XA_wind_get(short clnt_pid, AESPB *pb)
  445. {
  446.     XA_WINDOW *w;
  447.     XA_RECT_LIST *rl;
  448.     XA_SLIDER_WIDGET *slw;
  449.     short wind=pb->intin[0],cmd=pb->intin[1];
  450.     GRECT s,d;
  451.     
  452.     w=get_wind_by_handle(wind);
  453.  
  454.     if (w==NULL)
  455.     {
  456.         DIAGS(("WARNING:wind_get:Invalid window handle =%d\n",wind));
  457.         pb->intout[0]=0;            /* Invalid window handle, return error */
  458.         return XAC_DONE;
  459.     }
  460.  
  461.     pb->intout[0]=1;
  462.  
  463.     switch(cmd)
  464.     {
  465.         case WF_FIRSTXYWH:            /* Generate a rectangle list and return the first entry */
  466.             rl=rect_get_user_first(w);
  467.             if (rl)
  468.             {
  469.                 s.g_x=rl->x;
  470.                 s.g_y=rl->y;
  471.                 s.g_w=rl->w;
  472.                 s.g_h=rl->h;
  473.                 d.g_x=w->wx;
  474.                 d.g_y=w->wy;
  475.                 d.g_w=w->ww;
  476.                 d.g_h=w->wh;
  477.                 rc_intersect(&s, &d);
  478.                 pb->intout[1]=d.g_x;    /* Return the first rectangle coords */
  479.                 pb->intout[2]=d.g_y;
  480.                 pb->intout[3]=d.g_w;
  481.                 pb->intout[4]=d.g_h;
  482.             }else{
  483.                 pb->intout[1]=w->wx;    /* Totally obscured window, return w & h as 0 */
  484.                 pb->intout[2]=w->wy;
  485.                 pb->intout[3]=0;
  486.                 pb->intout[4]=0;
  487.             }            
  488.             break;
  489.             
  490.         case WF_NEXTXYWH:            /* Get next entry from a rectangle list */
  491.             rl=rect_get_user_next(w);
  492.             if (rl)
  493.             {
  494.                 s.g_x=rl->x;
  495.                 s.g_y=rl->y;
  496.                 s.g_w=rl->w;
  497.                 s.g_h=rl->h;
  498.                 d.g_x=w->wx;
  499.                 d.g_y=w->wy;
  500.                 d.g_w=w->ww;
  501.                 d.g_h=w->wh;
  502.                 rc_intersect(&s, &d);
  503.                 pb->intout[1]=d.g_x;    /* Return the first rectangle coords */
  504.                 pb->intout[2]=d.g_y;
  505.                 pb->intout[3]=d.g_w;
  506.                 pb->intout[4]=d.g_h;
  507.             }else{
  508.                 pb->intout[1]=w->wx;    /* Totally obscured window, return w & h as 0 */
  509.                 pb->intout[2]=w->wy;
  510.                 pb->intout[3]=0;
  511.                 pb->intout[4]=0;
  512.             }            
  513.             break;
  514.             
  515.         case WF_CURRXYWH:            /* Get the current coords of the window */
  516.             pb->intout[1]=w->x;        /* Return the window coords */
  517.             pb->intout[2]=w->y;
  518.             pb->intout[3]=w->w;
  519.             pb->intout[4]=w->h;
  520.             break;
  521.             
  522.         case WF_WORKXYWH:            /* Get the current coords of the window's user work area */
  523.             pb->intout[1]=w->wx+2;    
  524.             pb->intout[2]=w->wy+2;
  525.             pb->intout[3]=w->ww-4;
  526.             pb->intout[4]=w->wh-4;
  527.             break;
  528.             
  529.         case WF_PREVXYWH:            /* Get previous window position */
  530.             pb->intout[1]=w->prev_x;
  531.             pb->intout[2]=w->prev_y;
  532.             pb->intout[3]=w->prev_w;
  533.             pb->intout[4]=w->prev_h;
  534.             break;            
  535.             
  536.         case WF_FULLXYWH:            /* Get maximum window dimensions */
  537.             pb->intout[1]=root_window->x; 
  538.             pb->intout[2]=root_window->wy;    /* ensure the windows don't overlay the menu bar */
  539.             pb->intout[3]=root_window->w;
  540.             pb->intout[4]=root_window->h-root_window->wy;
  541.             break;
  542.             
  543.         case WF_BOTTOM:                /* Extension, gets the bottom window */
  544.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  545.             for(w=window_list; w->next; w=w->next);
  546.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  547.             pb->intout[1]=w->handle;    /* Return the window handle of the bottom window */
  548.             pb->intout[2]=w->owner;        /* Return the owner of the bottom window */
  549.             break;
  550.             
  551.         case WF_TOP:
  552.             Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  553.             w=window_list;
  554.             Psemaphore(3,WIN_LIST_SEMAPHORE,0L);
  555.             if (w)
  556.             {
  557.                 pb->intout[1]=w->handle;    /* Return the window handle */
  558.                 pb->intout[2]=w->owner;        /* AES4 specifies that you return the AESid of the owner here as well */
  559.                 if (w->next)                /* Is there a window below?  */
  560.                 {                            /* if there is, then AES4 says return it's handle here */
  561.                     pb->intout[3]=w->next->handle;
  562.                     pb->intout[4]=w->next->owner;    /* XaAES extentin - return the AESid of the app that owns the window below */
  563.                 }else{
  564.                     pb->intout[3]=0;
  565.                     pb->intout[4]=0;
  566.                 }
  567.             }else{
  568.                 pb->intout[1]=0;    /* No windows open - return an error */
  569.                 pb->intout[0]=0;
  570.             }
  571.             break;
  572.             
  573.         case WF_OWNER:                /* AES4 compatible stuff */
  574.             pb->intout[1]=w->owner;        /* The window owners AESid (==app_id) */
  575.             pb->intout[2]=w->is_open;    /* Is the window open? */
  576.             if (w->prev)                /* If there is a window above, return it's handle */
  577.             {
  578.                 pb->intout[3]=w->prev->handle;
  579.             }else{
  580.                 pb->intout[3]=0;
  581.             }
  582.             
  583.             if (w->next)                /* If there is a window below, return it's handle */
  584.             {
  585.                 pb->intout[4]=w->next->handle;
  586.             }else{
  587.                 pb->intout[4]=0;
  588.             }
  589.             break;
  590.             
  591.         case WF_VSLIDE:
  592.             if (w->active_widgets&VSLIDE)
  593.             {
  594.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  595.                 pb->intout[1]=slw->position;
  596.             }else{
  597.                 pb->intout[0]=pb->intout[1]=0;
  598.             }
  599.             break;
  600.             
  601.         case WF_HSLIDE:
  602.             if (w->active_widgets&HSLIDE)
  603.             {
  604.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  605.                 pb->intout[1]=slw->position;
  606.             }else{
  607.                 pb->intout[0]=pb->intout[1]=0;
  608.             }
  609.             break;
  610.             
  611.         case WF_HSLSIZE:
  612.             if (w->active_widgets&HSLIDE)
  613.             {
  614.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_HSLIDE].stuff);
  615.                 pb->intout[1]=slw->length;
  616.             }else{
  617.                 pb->intout[0]=pb->intout[1]=0;
  618.             }
  619.             break;
  620.             
  621.         case WF_VSLSIZE:
  622.             if (w->active_widgets&VSLIDE)
  623.             {
  624.                 slw=(XA_SLIDER_WIDGET*)(w->widgets[XAW_VSLIDE].stuff);
  625.                 pb->intout[1]=slw->length;
  626.             }else{
  627.                 pb->intout[0]=pb->intout[1]=0;
  628.             }
  629.             break;
  630.             
  631.         case WF_NEWDESK:
  632.             Psemaphore(2,ROOT_SEMAPHORE,-1L);
  633.             pb->intout[1]=((unsigned long)desktop&0xffff0000L)>>16;
  634.             pb->intout[2]=(unsigned long)desktop&0x0000ffffL;
  635.             Psemaphore(3,ROOT_SEMAPHORE,0L);
  636.             break;
  637.         
  638.         case WF_ICONIFY:
  639.             if(w->window_status==XAWS_ICONIFIED)
  640.             {
  641.                 pb->intout[1]=1;
  642.                 pb->intout[2]=iconify_w;
  643.                 pb->intout[3]=iconify_h;
  644.             }else{
  645.                 pb->intout[1]=0;
  646.             }
  647.             break;
  648.  
  649.         case WF_UNICONIFY:
  650.             pb->intout[1]=w->prev_x;
  651.             pb->intout[2]=w->prev_y;
  652.             pb->intout[3]=w->prev_w;
  653.             pb->intout[4]=w->prev_h;
  654.             break;
  655.         
  656.     }
  657.     
  658.     return XAC_DONE;
  659. }
  660.  
  661. short update_lock=FALSE;
  662. short mouse_lock=FALSE;
  663. short update_cnt=0;
  664. short mouse_cnt=0;
  665.  
  666. #define    EACCESS    36        /* access denied */
  667.  
  668. /* Wind_update handling */
  669. /* This handles locking for the update and mctrl flags. */
  670. /* !!!!New version - uses semphores to locking... */
  671. unsigned long XA_wind_update(short clnt_pid, AESPB *pb)
  672. {
  673.     short op=pb->intin[0];
  674.     long timeout=(op&0x100)?0L:-1L;    /* test for check-and-set mode */
  675.  
  676.     pb->intout[0]=1;
  677.  
  678.     switch(op)
  679.     {
  680.         case BEG_UPDATE:    /* Grab the update lock */
  681.         case BEG_UPDATE|0x100:
  682.             if (update_lock==clnt_pid)   /* Already owning it? */
  683.             {
  684.                 update_cnt++ ;
  685.                 break ;
  686.             }
  687.             if ( Psemaphore(2,UPDATE_LOCK,timeout)==-EACCESS )
  688.             {
  689.                 pb->intout[0]=0;    /* screen locked by different process */
  690.                 break ;
  691.             }
  692.             update_lock=clnt_pid;
  693.             update_cnt=1 ;
  694.             break;
  695.         case END_UPDATE:
  696.             if ((update_lock==clnt_pid)&&(--update_cnt==0))
  697.             {
  698.                 update_lock=FALSE;
  699.                 Psemaphore(3,UPDATE_LOCK,0);
  700.             }
  701.             break;
  702.         case BEG_MCTRL:        /* Grab the mouse lock */
  703.         case BEG_MCTRL|0x100:
  704.             if (mouse_lock==clnt_pid)   /* Already owning it? */
  705.             {
  706.                 mouse_cnt++ ;
  707.                 break ;
  708.             }
  709.             if ( Psemaphore(2,MOUSE_LOCK,timeout)==-EACCESS )
  710.             {
  711.                 pb->intout[0]=0;    /* mouse locked by different process */
  712.                 break ;
  713.             }
  714.             mouse_lock=clnt_pid;
  715.             mouse_cnt=1 ;
  716.             break;
  717.         case END_MCTRL:
  718.             if ((mouse_lock==clnt_pid)&&(--mouse_cnt==0))
  719.             {
  720.                 mouse_lock=FALSE;
  721.                 Psemaphore(3,MOUSE_LOCK,0);
  722.             }
  723.             break;
  724.     }
  725.     return XAC_DONE;
  726. }
  727.  
  728. unsigned long XA_wind_delete(short clnt_pid, AESPB *pb)
  729. {
  730.     XA_WINDOW *w=get_wind_by_handle(pb->intin[0]);
  731.  
  732.     if (w)
  733.     {
  734.         delete_window(w);
  735.     }
  736.     
  737.     pb->intout[0]=1;
  738.     
  739.     return XAC_DONE;
  740. }
  741.  
  742. /* Go through and check that all windows belonging to this client are */
  743. /* closed and deleted  */
  744. unsigned long XA_wind_new(short clnt_pid, AESPB *pb)
  745. {
  746.     XA_WINDOW *wl,*nwl;
  747.  
  748.     for(wl=window_list; wl; wl=nwl)
  749.     {
  750.         nwl=wl->next;
  751.         
  752.         if ((wl->owner==clnt_pid)&&(wl!=root_window))
  753.         {
  754.             close_window(wl);
  755.             delete_window(wl);
  756.         }
  757.     }
  758.     
  759.     return XAC_DONE;
  760. }
  761.  
  762. /*
  763.     wind_calc
  764. */
  765. unsigned long XA_wind_calc(short clnt_pid, AESPB *pb)
  766. {
  767.     XA_WINDOW *w_temp;
  768.     short request=pb->intin[0];
  769.     
  770. /* Create a temporary window with the required widgets */
  771.     w_temp=create_window(clnt_pid, pb->intin[1], pb->intin[2], pb->intin[3], pb->intin[4], pb->intin[5]);
  772.  
  773.     switch(request)
  774.     {
  775.         case WC_BORDER:                    /* We have to work out the border size ourselves here */
  776.             pb->intout[1]=2*w_temp->x - w_temp->wx;    /*if you want to prove the maths here, draw two boxes one inside */
  777.             pb->intout[2]=2*w_temp->y - w_temp->wy;    /* the other, then sit and think about it for a while.... */
  778.             pb->intout[3]=2*w_temp->w - w_temp->ww +1;
  779.             pb->intout[4]=2*w_temp->h - w_temp->wh +1;
  780.             break;
  781.         case WC_WORK:                    /* Work area was calculated when the window was created */
  782.             pb->intout[1]=w_temp->wx;
  783.             pb->intout[2]=w_temp->wy;
  784.             pb->intout[3]=w_temp->ww+1;
  785.             pb->intout[4]=w_temp->wh+1;
  786.             break;
  787.     }
  788.  
  789.     delete_window(w_temp);        /* Dispose of the temporary window we created */
  790.  
  791.     pb->intout[0]=1;
  792.     
  793.     return XAC_DONE;
  794. }
  795.